<?

class Record extends Set implements XMLConvertable, JSONConvertable {

	protected $tm;
	protected $acl;

	/**
	 * returns array of propertyes names
	 *
	 * @return array
	 */
	public function getDef() {
		return array_keys($this->elements);
	}

	public function __construct($fields, $tm) {
		$this->tm = $tm;
		if(!key_exists('acl', $fields)) throw new Exception('Virtual property ACL is not setted!');
		else {
			$this->acl = $fields['acl'];
			unset($fields['acl']);
		}
		if (!$fields) throw new Exception ('No result');
		parent::__construct($fields, true);
	}

	/**
	 * returns record id
	 *
	 * @return numeric
	 */
	public function id() {
		return $this->elements['id'];
	}

	/**
	 * checks, than user can do operation with record
	 *
	 * @param unknown_type $level
	 * @return bool
	 */
	public function can($level) {
		if (($this->acl & $level) == $level) return true;
		return false;
	}

	public function __get($name) {
		if ($name == 'acl') {
			return $this->acl;
		}
		return parent::__get($name);
	}

	public function __set($name, $val) {
		if($name == 'acl') {
			throw new Exception('unable to set virtual property Record::acl');
		}
		if (!$this->can(ACL_WRITE)) throw new Exception("Unable to change property `$name` of $this: no such ACL");
		return parent::__set($name, $val);
	}

	/**
	 * Returns definition WITHOUT acl
	 *
	 * @return array
	 */
	public function as_array() {
		return $this->elements;
	}

	/**
	 * Returns Record type
	 *
	 * @return RecordType
	 */
	public function get_type() {
		return $this->tm;
	}

	public function __toString() {
		return '[Record #'.$this->id.' of type '.$this->tm.']';
	}

	public function toXML(SimpleXMLElement &$parent = NULL)
	{
		$def = $this->elements;
		if ($parent === NULL) $xml = simplexml_load_string('<'.$this->tm.' id="'.@$this->id.'"/>');
		else {
			$xml = $parent->addChild($this->tm);
			$xml['id'] = $this->id;
		}
		unset($def['###']);
		foreach($def as $field => $val)
		{
			$xml->addChild($field, htmlspecialchars($val));
		}
		return $xml;
	}

	public function toJSON(){
		return json_encode($this->elements);
	}
}

?>